package ai;

import handlers.PetMvtHandler;
import influence_radii.Radial;

import java.util.ArrayList;
import java.util.List;

import map.Direction;
import map.GameMap;
import map.GameWorld;
import map.Position;
import scheduler.DuplicateEventException;
import scheduler.Scheduler;
import entity.Avatar;
import entity.Entity;

public class PetAI extends AI {

	private Scheduler scheduler;
	private int speed;
	
	public PetAI(Avatar avatar) {
		setAvatar(avatar);
		scheduler = Scheduler.getInstance();
		speed = 20;
	}
	
	@Override
	public boolean addEntity(Entity entity) {
		try {
			PetBrain brain = new PetBrain(entity);
			getEnemies().put(entity,brain);
			scheduler.schedule(brain, speed);
			return true;
		}
		catch(DuplicateEventException dee) {
			System.out.println(dee.toString());
			return false;
		}
	}

	@Override
	public void removeEntity(Entity entity) {
		scheduler.cancel(getEnemies().remove(entity));		
	}

	public void removeAll() {
		for(Entity e : getEnemies().keySet()) {
			removeEntity(e);
		}
	}
	private class PetBrain extends Brain {
		GameMap map;
		int range = 2;
		Entity pet;
		
		public PetBrain(Entity pet) {
			map = GameWorld.getInstance().getCurrentMap();
			move = new PetMvtHandler(pet);
			duration = 6;
			this.pet = pet;
		}

		@Override
		public void execute() {
			Position avatarPos = getAvatar().getPosition();
			List<Position> visiblePositions = getPositions();	
			if(visiblePositions.contains(avatarPos)) {	
				Entity enemy = senseForEnemies(visiblePositions);
				if(enemy != null) {
					moveTowardsEntity(enemy.getPosition());
				}
			}
			else {				
				moveTowardsEntity(getAvatar().getPosition());
			}
			
		}
		
		public Entity senseForEnemies(List<Position> visiblePositions) {
			
			for(Position pos : visiblePositions) {
				Entity enemy = map.getEntity(pos);
				if(enemy != null && !pos.equals(pet.getPosition()) && !pos.equals(getAvatar().getPosition())) {
					return enemy;
				}
			}
			return null;
		}
		
		public void moveTowardsEntity(Position ePos) {
			Position pos = pet.getPosition().substract(ePos);
			Direction dir = Direction.convert(pos);
			if(!move.move(dir)) {
				if(pos.getX() < 0) {
					if(!move.move(Direction.SOUTH))
						if(!move.move(Direction.SOUTHEAST))
							if(!move.move(Direction.NORTHEAST))
								move.move(Direction.NORTH);
				}
				else {
					if(!move.move(Direction.SOUTH))
						if(!move.move(Direction.SOUTHWEST))
							if(!move.move(Direction.NORTHWEST))
								move.move(Direction.NORTH);
				}
			}
		}
		public List<Position> getPositions() {
			Radial radial = new Radial();
			List<Position> visiblePositions = new ArrayList<Position>();
			for(int index = 0; index <= range; index++) {
				List<Position> tempPositions = radial.getRelAppsPts(index);
				
				for(Position pos : tempPositions) {
					visiblePositions.add(pos);
				}
			}
			for(Position pos : visiblePositions) {
				int x = pet.getPosition().getX();
				int y = pet.getPosition().getY();
				visiblePositions.set(visiblePositions.indexOf(pos), new Position(pos.getX()+x, pos.getY()+y));
			}
			return visiblePositions;
		}	
	}

}
